﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using RpgLibrary.WorldClasses;

using XRpgLibrary.TileEngine;
using XRpgLibrary.CharacterClasses;
using XRpgLibrary.ItemClasses;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace XRpgLibrary.WorldClasses
{
    public class Level
    {
        #region Field Region

        protected SpriteBatch spriteBatch;
        protected int width;
        protected int height;
        #endregion
        
        #region Property Region
        
        public TileMap Map { get; set; }
        public string MapName { get; set; }
        public int Width {
            get
            {
                return width;
            }
        }
        public int Height 
        {
            get
            {
                return height;
            }
        }
        #endregion
        
        #region Constructor Region

        public Level(LevelData data, SpriteBatch spriteBatch)
        {
            this.spriteBatch = spriteBatch;
            this.MapName = data.MapName;
            this.width = data.MapWidth;
            this.height = data.MapHeight;
        }

        public Level(TileMap tileMap, SpriteBatch spriteBatch)
        {
            Map = tileMap;
            this.spriteBatch = spriteBatch;
        }

        #endregion
        
        #region Method Region
        
        public void Update(GameTime gameTime)
        {
            Map.Update(gameTime);
        }

        public void Draw(GameTime gameTime, Camera camera)
        {
            Map.Draw(gameTime, spriteBatch, camera);
        }

        #endregion

        public static Level LoadFromData(LevelData data, SpriteBatch spriteBatch)
        {
            return new Level(data, spriteBatch);
        }

        internal void MoveToCharacter(Character character, string destinationPortalName)
        {
            MoveToCharacter(character, GetCharacterByName(destinationPortalName));
        }

        public Character GetCharacterByName(string destinationPortalName)
        {
            for (int i = 0, cnt = Map.MapLayers.Count; i < cnt; i++)
                for (int j = 0, jcnt = Map.MapLayers[i].CharacterManager.Characters.Count; j < jcnt; j++)
                    if (Map.MapLayers[i].CharacterManager.Characters[j].Name == destinationPortalName)
                        return Map.MapLayers[i].CharacterManager.Characters[j];

            throw new Exception(string.Format("Character '{0}' not found in level", destinationPortalName));
        }

        internal void MoveToCharacter(Character character, Character destination)
        {
            MoveCharacterTo(character, destination.Sprite.Position);
        }

        internal void MoveCharacterTo(Character character, Vector2 destination)
        {
            character.MoveTo(destination);
        }

        internal MapLayer GetLayerByName(string layerName)
        {
            for (int i = 0, cnt = Map.MapLayers.Count; i < cnt; i++)
                if (Map.MapLayers[i].Name == layerName)
                    return Map.MapLayers[i];

            return null;
        }

        internal void RemoveCharacter(Character character)
        {
            for (int i = 0, cnt = Map.MapLayers.Count; i < cnt; i++)
                Map.MapLayers[i].CharacterManager.Characters.Remove(character);
        }
    }
}